import traceback

import aiohttp
import parsel
from fastapi import APIRouter, Form
from re_common.baselibrary.utils.basehttpx import BaseHttpx
from re_common.baselibrary.utils.core.requests_core import USER_AGENT

from app.core.return_info import ReturnInfo, SUCCESS, FAILED, MsgCode

router = APIRouter()


@router.post("/down/cnkijournalref_first")
async def cnkijournalref_first(*, proxy: str = Form(None), rawid: str = Form(...)):
    return_info = ReturnInfo()
    url = r'https://kns.cnki.net/kcms/detail/frame/list.aspx?dbcode=CJFD&filename=%s&RefType=1&vl=' % rawid
    headers = {
        'Accept': '*/*',
        'Referer': 'https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=CJFD&filename=%s' % rawid,
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko'
    }
    Proxiesss = None
    if proxy:
        if proxy.startswith("http://"):
            Proxiesss = proxy
        else:
            Proxiesss = "http://" + proxy
    try:
        async with aiohttp.ClientSession() as client:
            async with client.get(url, proxy=Proxiesss, headers=headers, timeout=10) as r:
                text = await r.text()
                if r is not None:
                    if r.status == 200:
                        return_info.status = SUCCESS
                        return_info.msg_code = r.status
                        return_info.data = {"html": text}
                    else:
                        return_info.msg_code = r.status
                        return_info.msg = "状态码错误:" + str(r.status)
                        return_info.data = {"url": url, "proxy": proxy}
                else:
                    return_info.msg = "请求错误，没有返回Response"
                    return_info.data = {"url": url, "proxy": proxy}
                return return_info.todict()
    except Exception as e:
        print(traceback.print_exc())
        return_info.msg = "请求错误，没有返回Response"
        return_info.data = {"url": url, "proxy": proxy, "Exception": str(e)}
        return return_info.todict()


@router.post("/down/cnkijournalref_page")
async def cnkijournalref_page(*, proxy: str = Form(None), rawid: str = Form(...), dbcode: str = Form(...),
                              page: int = Form(...)):
    return_info = ReturnInfo()
    url = r'https://kns.cnki.net/kcms/detail/frame/list.aspx?dbcode=CJFD&filename=%s&RefType=1&vl=&CurDBCode=%s&page=%d' % (
        rawid, dbcode, page)
    headers = {
        'Accept': '*/*',
        'Referer': 'https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=CJFD&filename=%s' % rawid,
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko'
    }
    Proxiesss = None
    if proxy:
        if proxy.startswith("http://"):
            Proxiesss = proxy
        else:
            Proxiesss = "http://" + proxy
    try:
        async with aiohttp.ClientSession() as client:
            async with client.get(url, proxy=Proxiesss, headers=headers, timeout=10) as r:
                text = await r.text()
                if r is not None:
                    if r.status == 200:
                        return_info.status = SUCCESS
                        return_info.msg_code = r.status
                        return_info.data = {"html": text}
                    else:
                        return_info.msg_code = r.status
                        return_info.msg = "状态码错误:" + str(r.status)
                        return_info.data = {"url": url, "proxy": proxy}
                else:
                    return_info.msg = "请求错误，没有返回Response"
                    return_info.data = {"url": url, "proxy": proxy}
                return return_info.todict()
    except Exception as e:
        print(traceback.print_exc())
        return_info.msg = "请求错误，没有返回Response"
        return_info.data = {"url": url, "proxy": proxy, "Exception": str(e)}
        return return_info.todict()


@router.post("/down/cnki_detail")
def down_detail(proxy: str = Form(None), filename: str = Form(...)):
    return_info = ReturnInfo()
    knsUrl = r'https://kns.cnki.net/kcms/detail/detail.aspx?dbcode=CJFD&filename=%s' % filename
    bshttpx = BaseHttpx()
    headers = {
        'Accept': '*/*',
        'Accept-Encoding': 'Gzip',
        'Referer': 'https://www.cnki.net/',
        'User-Agent': USER_AGENT
    }
    sn = bshttpx.creat_sn(proxy=proxy,
                          headers=headers,
                          verify=False)
    BoolResult, errString, r = BaseHttpx().base_sn_httpx(knsUrl,
                                                         sn=sn,
                                                         timeout=(20, 30)
                                                         )
    if not BoolResult:
        return_info.status = FAILED
        code = ""
        if r:
            code = r.status
        return_info.msg_code = r.status
        return_info.msg = "请求失败：" + str(code) + ";  " + errString
        return return_info.todict()

    content = r.content
    if content.startswith(b'\xef\xbb\xbf'):  # 去掉 utf8 bom 头
        content = content[3:]
    htmlText = content.decode('utf8').strip()

    def isRightKNS(filename, htmlText):
        lowerText = htmlText.lower().strip()
        if lowerText.find(r'</html>') == -1:
            print('*** kns not endswith </html>')
            return False

        if lowerText.find(filename.lower()) < 0:
            print('*** kns not find filename: %s' % filename)
            return False

        feature = 'wxTitle'
        if htmlText.find(feature) < 0:
            print('*** kns not find %s' % feature)
            return False

        return True

    if not isRightKNS(filename, htmlText):
        return_info.status = FAILED
        return_info.msg = "验证没通过"
        return return_info.todict()
    return_info.status = SUCCESS
    return_info.data = htmlText
    return return_info.todict()


@router.post("/down/cnki_detail_pare")
def down_detail(html: str = Form(...)):
    return_info = ReturnInfo()
    sel = parsel.Selector(html)
    num = ""
    span_list = sel.xpath('//div[@class="info"]/div[@class="total"]/span')
    for span_tag in span_list:
        strings = span_tag.xpath("./label//text()").get()
        if strings.find("下载") > -1:
            num = span_tag.xpath("./b//text()").get()
            break
    return_info.status = SUCCESS
    return_info.data = num
    return return_info.todict()


@router.post("/down/cnki_detail_oversea")
async def cnkijournalref_page(*, proxy: str = Form(None), filename: str = Form(...)):
    def isRightOversea(filename, htmlText):
        lowerText = htmlText.lower()

        if lowerText.find(r'</html>') == -1:
            return False, '*** kns not endswith </html>'

        if (lowerText.find('layer7') > -1) and (lowerText.find('ddos') > -1):
            return False, '*** oversea find layer7 or ddos'

        if lowerText.find(filename.lower()) < 0:
            return False, '*** oversea not find filename: %s' % filename

        feature = 'The search of the literature does not exist!'.lower()
        if lowerText.find(feature) > 0:  # 海外版不存在正常
            return True, 'oversea %s no have %s' % (filename, feature)

        return True, ""

    return_info = ReturnInfo()
    headers = {
        'Accept': '*/*',
        'Accept-Encoding': 'Gzip',
        'Referer': 'https://www.cnki.net/',
        'User-Agent': USER_AGENT
    }
    overseaUrl = r'http://oversea.cnki.net/kcms/detail/detail.aspx?dbcode=CJFD&filename=%s' % filename
    bshttpx = BaseHttpx()
    bshttpx.creat_sn(proxy=proxy,
                     headers=headers,
                     verify=False)
    BoolResult, errString, r = bshttpx.base_sn_httpx(overseaUrl,
                                                     sn=bshttpx.sn,
                                                     timeout=(20, 30)
                                                     )
    if not BoolResult:
        return_info.status = FAILED
        return_info.msg = "下载失败，" + errString
        return return_info.todict()

    content = r.content
    if content.startswith(b'\xef\xbb\xbf'):  # 去掉 utf8 bom 头
        content = content[3:]
    htmlText = content.decode('utf8').strip()
    bools, msg = isRightOversea(filename, htmlText)
    if bools:
        return_info.status = SUCCESS
        return_info.msg = "下载成功"
        return_info.data = {"html":htmlText}
        return return_info.todict()
    else:
        if htmlText.find("所查找的文件不存在") > -1:
            return_info.status = FAILED
            return_info.msg_code = MsgCode.NO_RESOURCE
            return_info.msg = "下载失败"
            return_info.data = {"html": htmlText}
            return return_info.todict()
        return_info.status = FAILED
        return_info.msg = "下载失败，" + msg
        return_info.data = {"html": htmlText}
        return return_info.todict()
